package com.xiaoyy.sso.core.integration.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.IdcardUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaoyy.core.common.cache.CacheConst;
import com.xiaoyy.core.common.enums.BoolEnum;
import com.xiaoyy.core.common.enums.UserTypeEnum;
import com.xiaoyy.core.common.exception.AppException;
import com.xiaoyy.core.common.utils.PinyinUtil;
import com.xiaoyy.core.config.annotations.ApiService;
import com.xiaoyy.core.config.util.RedisUtil;
import com.xiaoyy.core.dict.integration.DictIntegration;
import com.xiaoyy.core.dict.utils.DictUtil;
import com.xiaoyy.sso.common.constant.SsoCacheConst;
import com.xiaoyy.sso.common.enums.UserDictEnum;
import com.xiaoyy.sso.common.vo.UserDeleteVO;
import com.xiaoyy.sso.common.vo.UserVO;
import com.xiaoyy.sso.core.dao.model.SysUser;
import com.xiaoyy.sso.core.dao.model.SysUserBasic;
import com.xiaoyy.sso.core.integration.UserIntegration;
import com.xiaoyy.sso.core.service.SysUserBasicService;
import com.xiaoyy.sso.core.service.SysUserOtherService;
import com.xiaoyy.sso.core.service.SysUserService;
import com.xiaoyy.sso.core.util.UserSecureUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 用户管理
 * */
@Service
@ApiService
public class UserIntegrationImpl implements UserIntegration {
    //手机号码正则
    private static Pattern cellphonePattern = Pattern.compile("^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|70)\\d{8}$");//1开头 第二位是3或4或5或7或8 总11位
    private static Pattern emailPattern = Pattern.compile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$");//复杂匹配

    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysUserBasicService sysUserBasicService;
    @Autowired
    SysUserOtherService sysUserOtherService;
    @Autowired
    DictUtil dictUtil;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    DictIntegration dictIntegration;
    @Override
    @Transactional
    public UserVO addUser(UserVO userVO) {
        if (StringUtils.isBlank(userVO.getUserName())){
            // 用户名不存在 则使用身份证作为用户名
            userVO.setUserName(userVO.getIdcard());
        }
        if (StringUtils.isBlank(userVO.getUserName())){
            // 身份也不存在 使用手机号码
            userVO.setUserName(userVO.getCellphone());
        }
        if (StringUtils.isBlank(userVO.getStatus())) {
            userVO.setStatus(BoolEnum.TRUE.getType());
        }
        //用户类型为空则设置为个人用户
        if (StringUtils.isBlank(userVO.getUserType())) {
            userVO.setUserType(UserTypeEnum.USER.getType());
        }
        checkRegister(userVO);
        if (StringUtils.isBlank(userVO.getUserPassword())) {
            //如果密码为空，设置初始密码为666666
            userVO.setUserPassword("f379eaf3c831b04de153469d1bec345e");
        }
        if (StringUtils.isNotBlank(userVO.getIdcard())){
            if (userVO.getBirthday()==null) {
                userVO.setBirthday(IdcardUtil.getBirthDate(userVO.getIdcard()));
            }
            if (StringUtils.isBlank(userVO.getSex())) {
                int gender = IdcardUtil.getGenderByIdCard(userVO.getIdcard());
                if (gender == 0) {
                    // 男
                    userVO.setSex("1");
                } else {
                    // 女
                    userVO.setSex("2");
                }
            }
        }
        if (StringUtils.isNotBlank(userVO.getFullName())) {
            userVO.setSpellAll(PinyinUtil.getPinYin(userVO.getFullName()));
            userVO.setSpellFirst(PinyinUtil.getAllFirstLetter(userVO.getFullName()));
        }
        SysUser sysUser = Convert.convert(SysUser.class, userVO);
        //生成userId
        String userId = IdUtil.fastSimpleUUID();
        userVO.setUserId(userId);
        sysUser.setUserId(userId);
        aesEncryptUser(userVO, sysUser);
        //设置校验码
        sysUser.setHashcode(UserSecureUtil.enSysUser(sysUser));
        SysUserBasic sysUserBasic = Convert.convert(SysUserBasic.class, userVO);
        sysUserBasic.setRegdate(DateUtil.date());

        sysUserBasic.setUserId(userId);

        sysUserService.save(sysUser);
        sysUserBasicService.save(sysUserBasic);

        return userVO;
    }

    @Override
    public UserVO editUser(UserVO userVO) {
        return null;
    }

    @Override
    public UserVO getUserDetail(String userId) {
        if (StringUtils.isBlank(userId)){
            throw new AppException("用户Id不能为空");
        }
        if (redisUtil.hHasKey(SsoCacheConst.SYS_USER_ID,userId)){
            return (UserVO) redisUtil.hget(SsoCacheConst.SYS_USER_ID,userId);
        }
        SysUser sysUser = getUser(userId);
        UserVO userVO = Convert.convert(UserVO.class, sysUser);
        SysUserBasic sysUserBasic = sysUserBasicService.getById(userId);
        if (sysUserBasic != null) {
            if (sysUserBasic.getDel().equals(BoolEnum.FALSE.getType())) {
                BeanUtils.copyProperties(sysUserBasic, userVO);
            }
        }
        //解密用户被加密的字段
        UserSecureUtil.aesDecryptUser(userVO);
        //转义数据字典值
        dictUtil.valueToName(userVO, Arrays.asList(UserDictEnum.values()));
        userVO.setOrgName(dictIntegration.getOrgNameById(userVO.getOrgId()));
        userVO.setOrgCode(dictIntegration.getOrgCodeById(userVO.getOrgId()));
        userVO.setUserPassword(null);
        redisUtil.hset(SsoCacheConst.SYS_USER_ID,userId,userVO);
        return userVO;
    }

    @Override
    public void resetPassword(UserVO userVO) {

    }

    @Override
    public void editPassword(UserVO userVO) {

    }

    @Override
    public void forgePassword(UserVO userVO) {

    }

    @Override
    public void editStatus(UserVO userVO) {

    }

    @Override
    public void deleteUser(UserDeleteVO userVO) {

    }

    @Override
    public void deleteUserBatch(UserDeleteVO userVO) {

    }

    /**
     * 用户加密字段
     */
    private void aesEncryptUser(UserVO userVO, SysUser sysUser) {
        //密码加密
        String password = UserSecureUtil.createPassword(sysUser.getUserId(), userVO.getUserPassword());
        sysUser.setUserPassword(password);
        //手机号码加密
        if (StringUtils.isNotBlank(userVO.getCellphone())) {
            sysUser.setCellphone(UserSecureUtil.aesEncrypt(userVO.getCellphone()));
        }
        //邮箱加密
        if (StringUtils.isNotBlank(userVO.getEmail())) {
            sysUser.setEmail(UserSecureUtil.aesEncrypt(userVO.getEmail()));
        }
        //身份证加密
        if (StringUtils.isNotBlank(userVO.getIdcard())) {
            sysUser.setIdcard(UserSecureUtil.aesEncrypt(userVO.getIdcard()));
        }
    }

    /**
     * 校验注册用户信息
     **/
    private void checkRegister(UserVO userVO) {
        if (StringUtils.isBlank(userVO.getUserType())){
            throw new AppException("用户类型不能为空");
        }
        if (UserTypeEnum.COMPANY.getType().equalsIgnoreCase(userVO.getUserType())){
            if (StringUtils.isBlank(userVO.getOrgId())){
                throw new AppException("单位不能为空");
            }
        }else if (UserTypeEnum.CLIENT.getType().equalsIgnoreCase(userVO.getUserType())){
            if (StringUtils.isBlank(userVO.getOrgId())){
                throw new AppException("所属应用不能为空");
            }
        }
        //校验数据字典值
        checkUserDict(userVO);
        // 校验用户名
        checkUserName(userVO);
        // 校验手机
        checkCellphone(userVO);
        // 校验身份证
        checkIdcard(userVO);
        // 校验邮箱
        checkEmail(userVO);

    }

    private void checkUserName(UserVO userVO) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getUserName,userVO.getUserName())
                .eq(SysUser::getUserType,userVO.getUserType())
                .eq(SysUser::getDel,BoolEnum.FALSE.getType());
        checkUserType(queryWrapper,userVO);
        List<SysUser> sysUsers = sysUserService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(sysUsers)) {
            throw new AppException("用户名已存在！");
        }
    }
    private void checkCellphone(UserVO userVO) {
        if (StringUtils.isNotBlank(userVO.getCellphone())) {
            Matcher m = cellphonePattern.matcher(userVO.getCellphone());
            if (!m.matches()){
                throw new AppException("请输入正确的手机号码");
            }
            QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUser::getCellphone, UserSecureUtil.aesEncrypt(userVO.getCellphone()))
                    .eq(SysUser::getUserType,userVO.getUserType())
                    .eq(SysUser::getDel,BoolEnum.FALSE.getType());
            checkUserType(queryWrapper,userVO);
            List<SysUser> sysUsers = sysUserService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(sysUsers)) {
                throw new AppException("手机已被注册！");
            }
        }
    }

    private void checkEmail(UserVO userVO) {
        if (StringUtils.isNotBlank(userVO.getEmail())) {
            Matcher m = emailPattern.matcher(userVO.getEmail());
            if (!m.matches()){
                throw new AppException("请输入正确的邮箱");
            }
            QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUser::getEmail,UserSecureUtil.aesEncrypt(userVO.getEmail()))
                    .eq(SysUser::getUserType,userVO.getUserType())
                    .eq(SysUser::getDel,BoolEnum.FALSE.getType());
            checkUserType(queryWrapper,userVO);
            List<SysUser> sysUsers = sysUserService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(sysUsers)) {
                throw new AppException("邮箱已被注册！");
            }
        }
    }

    private void checkIdcard(UserVO userVO) {
        if (StringUtils.isNotBlank(userVO.getIdcard())) {
            if (!IdcardUtil.isValidCard(userVO.getIdcard())){
                throw new AppException("请输入正确的身份证");
            }
            QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUser::getIdcard,UserSecureUtil.aesEncrypt(userVO.getIdcard()))
                    .eq(SysUser::getUserType,userVO.getUserType())
                    .eq(SysUser::getDel,BoolEnum.FALSE.getType());
            checkUserType(queryWrapper,userVO);
            List<SysUser> sysUsers = sysUserService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(sysUsers)) {
                throw new AppException("身份证已被注册！");
            }
        }
    }
    private void checkUserType(QueryWrapper<SysUser> queryWrapper, UserVO userVO){
        if (UserTypeEnum.COMPANY.getType().equalsIgnoreCase(userVO.getUserType())){
            queryWrapper.lambda().eq(SysUser::getOrgId, userVO.getOrgId());
        }else if (UserTypeEnum.CLIENT.getType().equalsIgnoreCase(userVO.getUserType())){
            queryWrapper.lambda().eq(SysUser::getClientId, userVO.getClientId());
        }
    }
    private void checkUserDict(UserVO userVO) {
        //校验数据字典值
        dictUtil.validValue(userVO, Arrays.asList(UserDictEnum.values()));

    }

    /**
     * 获取用户并校验用户信息是否存在
     */
    private SysUser getUser(String userId) {
        SysUser sysUser = sysUserService.getById(userId);
        if (sysUser == null) {
            throw new AppException("找不到用户信息");
        }
        if (BoolEnum.TRUE.getType().equalsIgnoreCase(sysUser.getDel())) {
            throw new AppException("该用户已被删除");
        }
        return sysUser;
    }
}
